﻿using System;
using System.Collections.Generic;
using Battle.Engine.InputData;
using Battle.Engine.LogicModel;
using Battle.Engine.util;

namespace Battle.Engine
{
    public class EngineData
    {
        public BaseCompute compute;
        public FRange range;                        //打击面的处理
        public EngineCallback callback;             //回调
        public RandomUtil random;                    //随机数接口
        public int roundNum;                        //回合数,从1开始
        public int roundMax;                        //最大回合数
        public double roundTime;                    //mxd 当前回合的时间,从每回合开始计时
        public FSkill ultimateSkill = null;         //当前是否有准备播放或者正在播放的大招
        public TableDataUtil tableDataUtil;         //当前数据接口
        public UIDUtil uidUtil;

        public List<FExport> exports;            //战斗每帧返回的输出数据

        public bool attackFirst;        //是否是攻击方先出手
        public CampType curRoundCamp;   //当前回合,如果回合已经结束表示下一回合的出手
        public FPlayer curPlayer;       //当前回合行动的是哪个玩家
        public FPlayer attacker;
        public FPlayer defender;
 
        public int currentOrderCount;//波数(1-N) 

        public void init(InFightData idata, BaseCompute compute)
        {
            random = new RandomUtil();
            range = new FRange();

            this.compute = compute;
            random.SetSeed(idata.seed);
            roundNum = 0;
            roundMax = idata.maxRoundCount;
            roundTime = 0;
            ultimateSkill = null;
            this.tableDataUtil = new TableDataUtil();
            this.uidUtil = new UIDUtil();
            this.exports = new List<FExport>();

            attackFirst = idata.attackFirst;
            if (attackFirst)
            {
                curRoundCamp = CampType.ATTACK;
            }
            else
            {
                curRoundCamp = CampType.DEFENCE;
            }

            attacker = new FPlayer();
            attacker.init(CampType.ATTACK, idata.attacker, this);
            defender = new FPlayer();
            defender.init(CampType.DEFENCE, idata.defender, this);
        }

        //得到剩余人数
        public int GetNumActor(CampType campType)
        {
            int num = 0;
            FPlayer player = null;
            if (campType == CampType.ATTACK)
                player = this.attacker;
            else if (campType == CampType.DEFENCE)
                player = this.defender;
            if (player == null)
                return 0;
            foreach (FActor actor in player.actors)
            {
                if (actor.state == FActorState.WAEKDEAD || actor.state == FActorState.DEAD)
                {
                    continue;
                }
                ++num;
            }
            return num;
        }

        //得到剩余的总血量
        public double GetNumHP(CampType campType)
        {
            double num = 0;
            FPlayer player = null;
            if (campType == CampType.ATTACK)
                player = this.attacker;
            else if (campType == CampType.DEFENCE)
                player = this.defender;
            if (player == null)
                return 0;
            foreach (FActor actor in player.actors)
            {
                if (actor.state == FActorState.WAEKDEAD || actor.state == FActorState.DEAD)
                {
                    continue;
                }
                num = num + actor.attribute.hp;
            }
            return num;
        }

        //当前是否有正在释放的技能
        public bool HasAnySkilling()
        {
            foreach (var actor in attacker.actors)
            {
                if (actor.doSkill != null)
                    return true;
            }
            foreach (var actor in defender.actors)
            {
                if (actor.doSkill != null)
                    return true;
            }
            return false;
        }

        //
        public FPlayer GetCurRoundPlayer()
        {
            if (curRoundCamp == CampType.ATTACK)
                return this.attacker;
            else
                return this.defender;
        }

        //获取一个目标
        //mxd 这里还没实现,等 战斗属性和逻辑完善了
        public FActor GetTargetActor(FActor src, CampType camp)
        {
            if (camp == CampType.ATTACK)
            {
                foreach (var actor in attacker.actors)
                {
                    return actor;
                }
            }
            else if (camp == CampType.DEFENCE)
            {
                foreach (var actor in defender.actors)
                {
                    return actor;
                }
            }
            return null;
        }

        public FPlayer getPlayerByCampType(CampType campType)
        {
            if (campType == CampType.ATTACK)
            {
                return this.attacker;
            }
            else
            {
                return this.defender;
            }
        }

        //得到目标actor正在被多少人攻击
        public int GetNumActorAttack(FActor hurtActor)
        {
            int num = 0;
            FPlayer enemy = getPlayerByCampType(hurtActor.player.enemyCamp);
            foreach (var actor in enemy.actors)
            {
                if (actor.state == FActorState.DEAD)
                {
                    continue;
                }
                if (actor.doSkill != null)
                {
                    if (actor.doSkill.isFirstCastStart && actor.doSkill.target.uniqueId.Equals(hurtActor.uniqueId))
                    {
                        if (actor.doSkill.state != FSkillState.LAST && actor.doSkill.state != FSkillState.FINISH)
                            ++num;
                    }
                    else if (!actor.doSkill.isFirstCastStart)
                    {//技能未释放时，需要遍历第一cast的所有人
                        foreach (var ca in actor.doSkill.castTargets)
                        {
                            if(ca.uniqueId.Equals(hurtActor.uniqueId))
                                ++num;
                        }
                    }
                }
                else if (actor.doUltimateSkill != null)
                {
                    if (actor.doUltimateSkill.isFirstCastStart && actor.doUltimateSkill.target.uniqueId.Equals(hurtActor.uniqueId))
                    {
                        if (actor.doUltimateSkill.state != FSkillState.LAST && actor.doUltimateSkill.state != FSkillState.FINISH)
                            ++num;
                    }
                    else if (!actor.doUltimateSkill.isFirstCastStart)
                    {//技能未释放时，需要遍历第一cast的所有人
                        foreach (var ca in actor.doUltimateSkill.castTargets)
                        {
                            if (ca.uniqueId.Equals(hurtActor.uniqueId))
                                ++num;
                        }
                    }
                }
            }
            return num;
        }

        public void ResetRound()
        {
            roundTime = 0;
            ultimateSkill = null;

            attacker.ResetRound(this);
            defender.ResetRound(this);
        }

        public FActor GetActorByUID(string uid)
        {
            foreach (var actor in attacker.actors)
            {
                if (actor.uniqueId == uid)
                    return actor;
            }
            foreach (var actor in defender.actors)
            {
                if (actor.uniqueId == uid)
                    return actor;
            }
            return null;
        }

        public FActor GetActorByFpid(int fpid, List<FActor> actors, FActor tactor, List<SelectLimitCondition> conditions)
        {
            foreach (var actor in actors)
            {
                if (actor.IsDetectionPosition(fpid))
                {
                    if (IsActorMatchCondition(actor, tactor, conditions))
                    {//判断是否满足限制条件
                        return actor;
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// 限制条件
        /// </summary>
        /// <param name="isSelectDead">是否已在死亡状态</param>
        /// <param name="isSelectInvisible">是否隐身</param>
        /// <param name="isSelectInvincible">是否无敌</param>
        /// <returns></returns>
        public List<SelectLimitCondition> LimitConditions(bool isSelectWeakDead, bool isSelectInvisible, bool isSelectInvincible)
        {
            List<SelectLimitCondition> conditions = new List<SelectLimitCondition>();
            if (!isSelectWeakDead)
            {
                conditions.Add(SelectLimitCondition.Alive);
            }
            if (!isSelectInvisible)
            {
                conditions.Add(SelectLimitCondition.NoInvisible);
            }
            if (!isSelectInvincible)
            {
                conditions.Add(SelectLimitCondition.NoInvincible);
            }
            return conditions;
        }

        public bool IsActorMatchCondition(FActor actor, FActor target, List<SelectLimitCondition> conditions)
        {
            if (actor == null || actor.state == FActorState.DEAD)
            {//已经真实死亡的人默认不生效
                return false;
            }
            foreach (var condition in conditions)
            {
                switch (condition)
                {
                    case SelectLimitCondition.Alive:
                        if (actor.state == FActorState.WAEKDEAD)
                        {
                            return false;
                        }
                        break;
                    case SelectLimitCondition.NoInvisible:
                        if (actor.stateManager.IsInvisible)
                        {
                            if (target != null && target.uniqueId.Equals(actor.uniqueId))
                            {//如果当前人已经被设定为目标了，则隐身无效

                            }
                            else
                            {
                                return false;
                            }
                        }   
                        break;
                    case SelectLimitCondition.NoInvincible:
                        if (actor.stateManager.IsInvincible)
                        {
                            return false;
                        }
                        break;
                }
            }
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="isSkill">是否是技能触发</param>
        /// <param name="strategy">打击范围</param>
        /// <param name="actor">当前攻击者的actor</param>
        /// <param name="tactor">对方第1个目标,如果是技能Cast为技能开始前选中的第1个目标</param>
        /// <param name="conditions"></param>
        /// <returns></returns>
        public List<FActor> SelectTargetActors(bool isSkill, int strategy, FActor actor, FActor tactor, List<SelectLimitCondition> conditions)
        {
            return range.SelectTargetActors(isSkill, strategy, actor, tactor, conditions, this);
        }

    }
}
